//
//  EasyUdpSocket.m
//  wf-soket-new
//
//  Created by Rankin on 16/5/29.
//  Copyright © 2016年 Rankin. All rights reserved.
//

#import "EasyUdpSocket.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <sys/ioctl.h>
#import <net/if.h>
#import <netdb.h>
@implementation EasyUdpSocket
- (id)init{
    self = [super init];
    if (self) {
        self.sockDescriptor = -1;
    }
    
    return self;
}
- (NSArray*) broadcast:(void*)datas{
    
    return [self broadcast:@"255.255.255.255" withDatas:datas waitFor:5];
}
- (NSArray*) broadcast:(NSString*)host withDatas:(void*)datas waitFor:(int)timeout{
    NSMutableArray *retArr = [[NSMutableArray alloc]init];
    
    if (_sockDescriptor==-1) {
        _sockDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (_sockDescriptor<0) {
            NSLog(@"fail to create udp");
            return nil;
        }
    }
    
    
    struct timeval timeoutval;
    timeoutval.tv_sec = timeout;
    timeoutval.tv_usec = 0;
    
    setsockopt(_sockDescriptor,SOL_SOCKET , SO_RCVTIMEO, &timeoutval, sizeof(timeoutval));
    
    struct sockaddr_in addr;
    
    
    addr.sin_family = AF_INET;
    addr.sin_addr = *(struct in_addr *)gethostbyname([host UTF8String])->h_addr_list[0];
    //    addr.sin_addr.s_addr = inet_addr(INADDR_BROADCAST);
    addr.sin_port = htons(31500);
    //    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    int broadcastEnable=1;
    int ret=setsockopt(_sockDescriptor, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
    if (ret==-1) {
        return nil;
    }
    
    ssize_t ac = sendto(_sockDescriptor, datas, strlen(datas), 0, (struct sockaddr*)&addr, sizeof(addr));
    if (ac<0) {
        return nil;
    }
    
    struct sockaddr_in from_addr;
    socklen_t size = sizeof(from_addr);
   
    ssize_t len = 0;
    void* pool = NULL;
    while (1) {
        pool = malloc(39216);
        len = recvfrom(_sockDescriptor, pool, 39216, 0, (struct sockaddr*)&from_addr, &size);
        if (len==-1) {
            break;
        }
        pool=realloc(pool, len);
        NSLog(@"%s",pool);
        NSDictionary* recvDic = @{
                                  @"datas":[NSString stringWithFormat:@"%s",pool] ,
                                 @"ip":[NSString stringWithFormat:@"%s",inet_ntoa(from_addr.sin_addr)]
                                 };
        [retArr addObject:recvDic];
    }
    
    free(pool);

    
    return retArr;
    
    
}

-(void)close{
    close(_sockDescriptor);
    _sockDescriptor = -1;
}
@end
